package com.hse.network;

import com.hse.network.exceptions.NetworkException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Created by IntelliJ IDEA.
 * User: Lexa
 * Date: May 30, 2009
 * Time: 1:25:05 PM
 * To change this template use File | Settings | File Templates.
 */
public class CoordinatorEndDeviceFunctionalTests {
    private final Long MAC_ADDRESS_1 = (long) 0;
    private final Long MAC_ADDRESS_2 = (long) 1;
    private final Short PAN_ID = (short) 12345;
    private ICoordinator coordinator;
    private IEndDevice endDevice;

    @Before
    public void init() throws InstantiationException, NetworkException {
        coordinator = new Coordinator(TestConfigurator.PORT_NAME_1, MAC_ADDRESS_1);
        coordinator.createNetwork(PAN_ID);

        endDevice = new EndDevice(TestConfigurator.PORT_NAME_2, MAC_ADDRESS_2);
    }

    @After
    public void delete() {
        coordinator.close();
        endDevice.close();
    }

    @Test(timeout = 3000)
    public void scanNetworkTest() throws NetworkException {
        final Network[] networks = endDevice.scan();
        Assert.assertEquals(1, networks.length);
        Assert.assertEquals(PAN_ID, networks[0].getPanId());
    }

    @Test(timeout = 3000)
    public void connectToNetwork() throws NetworkException {
        endDevice.connect(PAN_ID);
    }

    @Test(timeout = 3000)
    public void connectAndAccept() throws NetworkException {
        endDevice.connect(PAN_ID);
        final ICoordinatorClient client = coordinator.accept();
        Assert.assertNotNull(client);
    }

    @Test(timeout = 3000)
    public void canAccept() throws NetworkException {
        Assert.assertFalse(coordinator.canAccept());
        endDevice.connect(PAN_ID);
        Assert.assertTrue(coordinator.canAccept());
        coordinator.accept();
        Assert.assertFalse(coordinator.canAccept());
    }

    @Test(timeout = 3000)
    public void recvSend() throws NetworkException {
        endDevice.connect(PAN_ID);
        final ICoordinatorClient client = coordinator.accept();
        byte[] sentData = "Hello World!Hello World!Hello World!Hello World!Hello World!".getBytes();
        client.send(sentData);
        byte[] recvData = endDevice.recv();
        Assert.assertArrayEquals(sentData, recvData);

        endDevice.send(sentData);
        recvData = client.recv();
        Assert.assertArrayEquals(sentData, recvData);
    }

    @Test(timeout = 3000)
    public void canRead() throws NetworkException, InterruptedException {
        endDevice.connect(PAN_ID);
        final ICoordinatorClient client = coordinator.accept();

        Assert.assertFalse(endDevice.canRead());
        byte[] sentData = "Hello World!Hello World!Hello World!Hello World!Hello World!".getBytes();
        client.send(sentData);
        Thread.sleep(500);
        Assert.assertTrue(endDevice.canRead());
        endDevice.recv();
        Assert.assertFalse(endDevice.canRead());

        Assert.assertFalse(client.canRead());
        endDevice.send(sentData);
        Thread.sleep(500);
        Assert.assertTrue(client.canRead());
        client.recv();
        Assert.assertFalse(client.canRead());
    }
}
